# Maintainer: Jakub Jirutka <jakub@jirutka.cz>
# Contributor: G.J.R. Timmer <gjr.timmer@gmail.com>
# Contributor: Jakub Jirutka <jakub@jirutka.cz>
_pkgname=postgresql
pkgver=14.10
pkgrel=0
_majorver=${pkgver%%.*}
# Should this aport provide libpq* and libecpg*? true/false
# Exactly one postgresql aport must be the default one!
_default_ver=false
pkgname=$_pkgname$_majorver
pkgdesc="A sophisticated object-relational DBMS, version $_majorver"
url="https://www.postgresql.org/"
arch="all"
license="PostgreSQL"
_llvmver=14
depends="$pkgname-client postgresql-common tzdata"
depends_dev="
	libpq-dev
	libecpg-dev
	clang$_llvmver
	icu-dev
	llvm$_llvmver
	openssl-dev>3
	"
checkdepends="diffutils"
makedepends="$depends_dev
	libxml2-dev
	linux-headers
	llvm$_llvmver-dev
	openldap-dev
	perl-dev
	python3-dev
	readline-dev
	tcl-dev
	util-linux-dev
	zlib-dev
	bison flex
	"
pkgusers="postgres"
pkggroups="postgres"
install="$pkgname.post-install $pkgname.pre-deinstall"
provider_priority=$_majorver
provides="postgresql"
replaces="postgresql"  # for backward compatibility
$_default_ver && subpackages="
	libpq
	libpq-dev:libpq_dev
	libecpg
	libecpg-dev:libecpg_dev
	"
subpackages="
	$subpackages
	$pkgname-client
	$pkgname-jit
	$pkgname-contrib
	$pkgname-plperl
	$pkgname-plperl-contrib:plperl_contrib
	$pkgname-plpython3
	$pkgname-plpython3-contrib:plpython3_contrib
	$pkgname-pltcl
	$pkgname-contrib-jit:contrib_jit
	$pkgname-dev
	$pkgname-doc
	$pkgname-openrc
	"
source="https://ftp.postgresql.org/pub/source/v$pkgver/postgresql-$pkgver.tar.bz2
	initdb.patch
	perl-rpath.patch
	per-version-dirs.patch
	unix_socket_directories.patch
	disable-broken-tests.patch
	disable-test-collate.icu.utf8.patch
	disable-html-docs.patch
	remove-libecpg_compat.patch
	czech-snowball-stemmer.patch
	make-split-headers.patch
	jit-datalayout-mismatch-on-s390x-and-x86.patch
	pg_config-add-major-version.patch
	dont-use-locale-a-on-musl.patch
	icu-collations-hack.patch
	libpgport-pkglibdir.patch.txt
	external-libpq.patch.txt
	fix-test-temp-schema-cleanup.patch

	pltcl_create_tables.sql
	"
builddir="$srcdir/$_pkgname-$pkgver"

# secfixes:
#   14.10-r0:
#     - CVE-2023-5868
#     - CVE-2023-5869
#     - CVE-2023-5870
#   14.9-r0:
#     - CVE-2023-39418
#     - CVE-2023-39417
#   14.8-r0:
#     - CVE-2023-2454
#     - CVE-2023-2455
#   14.7-r0:
#     - CVE-2022-41862
#   14.5-r0:
#     - CVE-2022-2625
#   14.3-r0:
#     - CVE-2022-1552
#   14.1-r0:
#     - CVE-2021-23214
#     - CVE-2021-23222
#   13.4-r0:
#     - CVE-2021-3677
#   13.3-r0:
#     - CVE-2021-32027
#     - CVE-2021-32028
#     - CVE-2021-32029
#   13.2-r0:
#     - CVE-2021-3393
#     - CVE-2021-20229
#   12.5-r0:
#     - CVE-2020-25694
#     - CVE-2020-25695
#     - CVE-2020-25696
#   12.4-r0:
#     - CVE-2020-14349
#     - CVE-2020-14350
#   12.2-r0:
#     - CVE-2020-1720
#   11.5-r0:
#     - CVE-2019-10208
#     - CVE-2019-10209
#   11.4-r0:
#     - CVE-2019-10164
#   11.3-r0:
#     - CVE-2019-10129
#     - CVE-2019-10130
#   11.1-r0:
#     - CVE-2018-16850
#   10.5-r0:
#     - CVE-2018-10915
#     - CVE-2018-10925
#   10.4-r0:
#     - CVE-2018-1115
#   10.3-r0:
#     - CVE-2018-1058
#   10.2-r0:
#     - CVE-2018-1052
#     - CVE-2018-1053
#   10.1-r0:
#     - CVE-2017-15098
#     - CVE-2017-15099
#   9.6.4-r0:
#     - CVE-2017-7546
#     - CVE-2017-7547
#     - CVE-2017-7548
#   9.6.3-r0:
#     - CVE-2017-7484
#     - CVE-2017-7485
#     - CVE-2017-7486

_bindir=usr/libexec/$pkgname
_datadir=usr/share/$pkgname
_docdir=usr/share/doc/$pkgname
_mandir=$_datadir/man
_includedir=usr/include/postgresql
# Directory for server-related libraries. This is hard-coded in
# per-version-dirs.patch.
_srvlibdir=usr/lib/$pkgname

# Programs to be included in the -client subpackage.
# TODO: This was probably originally copied from Debian and I have no idea
#   why these are considered as front-end (client) programs and the rest of
#   the programs are not. So it should be reviewed.
_client_cmds="
	clusterdb
	createdb
	createuser
	dropdb
	dropuser
	pg_amcheck
	pg_basebackup
	pg_dump
	pg_dumpall
	pg_isready
	pg_receivewal
	pg_recvlogical
	pg_restore
	pg_verifybackup
	pgbench
	psql
	reindexdb
	vacuumdb
	"

prepare() {
	default_prepare

	if $_default_ver; then
		cp -rl "$builddir" "$builddir-ifaces"
	else
		msg 'external-libpq.patch'
		patch -p1 < "$srcdir"/external-libpq.patch.txt
	fi
	# Note: This must be applied after clonning $builddir-ifaces.
	patch -p1 < "$srcdir"/libpgport-pkglibdir.patch.txt
}

build() {
	export LLVM_CONFIG="/usr/lib/llvm$_llvmver/bin/llvm-config"
	export PYTHON=/usr/bin/python3
	export CFLAGS="${CFLAGS/-Os/-O2}"
	export CPPFLAGS="${CPPFLAGS/-Os/-O2}"
	# older clang versions don't have a 'clang' exe anymore.
	export CLANG=clang-$_llvmver

	_configure --with-ldap
	make world

	if $_default_ver; then
		cd "$builddir-ifaces"

		_configure --without-ldap
		local dir; for dir in include common port interfaces bin/pg_config; do
			make -C src/$dir
		done
	fi
}

_configure() {
	local _extra_opts
	# When disable-spinlocks is no longer required - check postgresql-bdr package.
	case "$CARCH" in
		riscv64) _extra_opts='--disable-spinlocks';;
	esac

	./configure \
		--build=$CBUILD \
		--host=$CHOST \
		--prefix=/usr \
		--bindir=/$_bindir \
		--datarootdir=/usr/share \
		--datadir=/$_datadir \
		--docdir=/$_docdir \
		--includedir=/$_includedir \
		--libdir=/usr/lib \
		--mandir=/$_mandir \
		--sysconfdir=/etc/postgresql \
		--disable-rpath \
		--with-system-tzdata=/usr/share/zoneinfo \
		--with-libxml \
		--with-openssl \
		--with-uuid=e2fs \
		--with-llvm \
		--with-icu \
		--with-perl \
		--with-python \
		--with-tcl \
		$_extra_opts \
		"$@"
}

check() {
	_run_tests src/test
	_run_tests src/pl
	_run_tests contrib
}

package() {
	make DESTDIR="$pkgdir" install install-docs

	if $_default_ver; then
		cd "$builddir-ifaces"

		# Override libpq and libecpg files with the build without LDAP support.
		local dir; for dir in common port interfaces bin/pg_config; do
			make -C src/$dir DESTDIR="$pkgdir" bindir=/usr/bin install
		done
		make -C src/include DESTDIR="$pkgdir" install-interfaces
	fi

	cd "$pkgdir"

	# Duplicate of usr/bin/ecpg.
	rm -f ./$_bindir/ecpg

	mkdir -p ./usr/bin
	ln -s /$_bindir/postgres ./usr/bin/postgres$_majorver

	# This file is used by pg_versions and init script.
	echo "$_majorver" > ./$_bindir/PG_VERSION

	install -d -m750 -o postgres -g postgres \
		./etc/postgresql$_majorver \
		./var/lib/postgresql \
		./var/log/postgresql

	local server_cmds=$(_setdiff "$(ls -1 $_bindir)" "$_client_cmds pg_config ecpg PG_VERSION")
	[ "$server_cmds" ] || die 'package: variable server_cmds is empty'

	# These commands are symlinked to /usr/bin by pg_versions script after
	# installation.
	provides="$provides $(echo "$server_cmds" | sed 's/^/cmd:&/')"
}

libpq() {
	pkgdesc="PostgreSQL client library"
	depends=""
	replaces=""

	amove usr/lib/libpq.so.*
}

libpq_dev() {
	pkgdesc="PostgreSQL client library (development files)"
	depends=""
	replaces=""

	amove usr/bin/pg_config

	amove $_includedir/internal/*
	amove $_includedir/libpq-*.h
	amove $_includedir/libpq/*
	amove $_includedir/pg_config*.h
	amove $_includedir/postgres_ext.h

	amove usr/lib/libpq.*
	amove usr/lib/libpgcommon*.a
	amove usr/lib/libpgport*.a
	amove usr/lib/pkgconfig/libpq.pc
}

libecpg() {
	pkgdesc="ECPG - Embedded SQL in C"
	depends=""
	provides="postgresql-libs"  # for backward compatibility (Alpine <3.15)
	replaces="$provides"  # for backward compatibility (Alpine <3.15)

	amove usr/lib/libecpg.so.*
	amove usr/lib/libpgtypes.so.*
}

libecpg_dev() {
	pkgdesc="ECPG - Embedded SQL in C (development files)"
	depends="libpq-dev=$pkgver-r$pkgrel"
	replaces=""

	amove usr/bin/ecpg

	amove $_includedir/ecpg*.h
	amove $_includedir/informix/*
	amove $_includedir/pgtypes*.h
	amove $_includedir/sql3types.h
	amove $_includedir/sqlca.h
	amove $_includedir/sqlda*.h

	amove usr/lib/libecpg.*
	amove usr/lib/libpgtypes.*
	amove usr/lib/pkgconfig/libecpg.pc
	amove usr/lib/pkgconfig/libpgtypes.pc
}

client() {
	pkgdesc="PostgreSQL client"
	depends="postgresql-common"
	_subpkg_common

	local cmd; for cmd in $_client_cmds; do
		amove $_bindir/$cmd
		# These commands are symlinked to /usr/bin by pg_versions script after
		# installation.
		provides="$provides cmd:$cmd"
	done
	amove $_bindir/PG_VERSION
}

jit() {
	pkgdesc="Just-in-time compilation support for PostgreSQL"
	depends="$pkgname=$pkgver-r$pkgrel"
	_subpkg_common

	amove $_srvlibdir/bitcode/*
	amove $_srvlibdir/llvmjit.so
	amove $_srvlibdir/llvmjit_types.bc
}

contrib() {
	pkgdesc="Extension modules distributed with PostgreSQL"
	depends="$pkgname=$pkgver-r$pkgrel"
	_subpkg_common

	cd "$builddir"

	# Avoid installing plperl and plpython extensions, these will be
	# installed into separate subpackages.
	sed -Ei -e 's/(.*_plperl)/#\1/' \
		-e 's/(.*_plpython)/#\1/' \
		contrib/Makefile

	make -C contrib DESTDIR="$subpkgdir" install

	_contrib_common

	provides="$provides $(ls -1 "$subpkgdir"/$_bindir | sed 's/^/cmd:&/')"
}

pltcl() {
	pkgdesc="PL/Tcl procedural language for PostgreSQL"
	depends="$pkgname=$pkgver-r$pkgrel pgtcl"
	_subpkg_common

	amove $_srvlibdir/pltcl.so
	amove $_datadir/extension/pltcl*

	install -m 644 "$srcdir"/pltcl_create_tables.sql -t "$subpkgdir"/$_datadir/
}

plperl() {
	pkgdesc="PL/Perl procedural language for PostgreSQL"
	depends="$pkgname=$pkgver-r$pkgrel"
	_subpkg_common

	amove $_srvlibdir/plperl.so
	amove $_datadir/extension/plperl*
}

plperl_contrib() {
	_plcontrib plperl "PL/Perl"

	cd "$builddir"
	make -C contrib/hstore_plperl DESTDIR="$subpkgdir" install

	_contrib_common
}

plpython3() {
	pkgdesc="PL/Python3 procedural language for PostgreSQL"
	depends="$pkgname=$pkgver-r$pkgrel python3"
	_subpkg_common

	amove $_srvlibdir/plpython3.so
	amove $_datadir/extension/plpython*
}

plpython3_contrib() {
	_plcontrib plpython3 "PL/Python 3"

	cd "$builddir"
	make -C contrib/hstore_plpython DESTDIR="$subpkgdir" install
	make -C contrib/ltree_plpython DESTDIR="$subpkgdir" install

	cd "$subpkgdir"/$_datadir/extension/
	rm ./*plpython2* ./*plpythonu*

	_contrib_common
}

contrib_jit() {
	pkgdesc="Extension modules distributed with PostgreSQL (JIT support)"
	depends="$pkgname-contrib=$pkgver-r$pkgrel"
	install_if="$pkgname-jit $pkgname-contrib=$pkgver-r$pkgrel"
	_subpkg_common

	amove $_srvlibdir/bitcode/*
}

dev() {
	default_dev
	_subpkg_common
	replaces=""

	amove $_srvlibdir/pgxs/*
}

doc() {
	default_doc
	_subpkg_common

	amove $_mandir
}

openrc() {
	default_openrc
	depends="postgresql-common-openrc"

	mkdir -p "$subpkgdir"
}

_plcontrib() {
	local subname="$1"
	pkgdesc="$2 extension modules distributed with PostgreSQL"
	depends="$pkgname-$subname=$pkgver-r$pkgrel"
	install_if="$pkgname-$subname=$pkgver-r$pkgrel $pkgname-contrib=$pkgver-r$pkgrel"
	_subpkg_common
}

_subpkg_common() {
	provides="postgresql${subpkgname#$pkgname}"
	replaces="$provides"  # for backward compatibility
}

_contrib_common() {
	# Move headers, bitcode and docs from subpackage back to pkgdir, so it
	# can be catched by subsequent split functions.
	local dir; for dir in $_includedir $_srvlibdir/bitcode $_docdir; do
		[ -d "$subpkgdir"/$dir ] || continue

		mkdir -p "$pkgdir"/$dir
		cp -rf "$subpkgdir"/$dir/* "$pkgdir"/$dir/
		rm -rf "$subpkgdir"/$dir/*
		rmdir -p "$subpkgdir"/$dir || true
	done
}

_run_tests() {
	local path="$1"; shift

	msg "Running test suite at $path..."
	# Note: some tests fail when running in parallel.
	make -k -j 1 -C "$path" "$@" check MAX_CONNECTIONS=5 || {
		printf "\n%s\n\n" "Trying to find all regression.diffs files in build directory..." >&2
		find "$path" -name regression.diffs | while read -r file; do
			echo "=== test failure: $file ===" >&2
			cat "$file" >&2
		done
		return 1
	}
}

# $1: whitespace-separated items of set A
# $2: whitespace-separated items of set B
# stdout: newline-separated items of A - B
_setdiff() {
	python3 -c 'import sys;print("\n".join(set(sys.argv[1].split()).difference(set(sys.argv[2].split()))))' "$@"
}

sha512sums="
f546e62eb158efdeecf091271ee60945604ca7f3683f0b259ee18eb682431158e282bf4f81d8df304c956919788f8077e72aa47c467d32d6aef1ccfe470862a5  postgresql-14.10.tar.bz2
73080f61ae274a214966d2d010de49c8c90eb3180e4f56d86a9e23063eaddbe7f8d2c40ed414591c16bc9cfe88577866af2a965c2b6effb54965d19ef96a3fa9  initdb.patch
27e00b58fe5c3899c66fc0dde51846c14701bcfedd132b106d676783ba603e8cbdc6e620f29b52dc892bdaa9302052788cf5e575a1659f61c017a12e0d2ee4d0  perl-rpath.patch
92d28f91b57a01afc81a00d386e87b9e2aa812f341a1578f262af372ee905530205592eda595111827582acceacd1bf244d1df130330003f05e74e4ddb5a7c4f  per-version-dirs.patch
d0040599d7646b709af4e3413bf0c228090f256395e806f3fee230ccc6037ed9c0df1cd160d01b6a73b25a742fdd3fb070733a14a78f53d297fbdbbb44f6f878  unix_socket_directories.patch
c4179fcd8b71791cdc41ea7b622cf82e9bd42ac1de66999234b98a83c0c508c79c492a9301274fe859c06a3f1a8b17b53ab97541ab76801a985f8f0b9b8716e7  disable-broken-tests.patch
30ce932ca34ffcd78ec20e7ead09faa3abe147faea776e073628985c7d9aa3a40b1e6f2ee681a0ffe5dc502770eea333cb752ed34c5471a9cee663bc5f6225e3  disable-test-collate.icu.utf8.patch
2e33e1ae38d60e0daf3ed18e6eaa9ddf6762b4b1bb7e51f1d2690e3df9d602aa1a700e603ba3ee69314a75a963131c7dc67c1b1f8b7eb5564e9c4253e81a4db4  disable-html-docs.patch
d8eb4274a54b94bed4a2ded7ae775c5a95ca0f051b831b859ccf78bf6d2ea6fe89a9a0611771f6ad85573995a7e3af1fdf5859e20cae3267a52239f12e1b61c3  remove-libecpg_compat.patch
673707b331cd09c105d18f39e83ec39371886d5d8cf706b6ebbd30ace294fa3377c391bea1ab409c001644c90ac718e3250cbc4acd9224bc0e7ac1f86c832424  czech-snowball-stemmer.patch
5262f4944844bccc839c4441570b9eb2e0792390234ebfdb8ebb7b83380ce5f5de84b038cb03045526da202a185af9c3972c2ae1b9e0e743a95c6e84f4621cf9  make-split-headers.patch
c24986becfd73546a062612335e53b4da34829e42a0c30e85ed7481924f13b1fd0a0e5079d680905a52afea1e99f2210cc3692c529a34a74cd6961c88cce9163  jit-datalayout-mismatch-on-s390x-and-x86.patch
7790e4e4374f7bdc6b4484ba87a5fa709d30d3cbdce61ee7bf9c5dfce40cb51c7bd54ab42f4050fb48eede08ef573624d819128e57cc8c976e01202854740308  pg_config-add-major-version.patch
b0688d66fdd7d612c24d9aa69bdd80d30787d2d6409b4524c79b41797144fc743213460e6de9c536bfb72da089f92cf89731f15137b1407fd04ca97fd393bfd2  dont-use-locale-a-on-musl.patch
0ebee9cf40a7e84e8eda3998c0dd0f7601d9288233411f45f9710fcafc5f4ca3e4a91e8e1b552cc4f4d2c0e8fa6512703b1094e501f132ea2842db0398e62934  icu-collations-hack.patch
cde5fbf5a39e5de18a40ec1d9ac919dcf166e0ca178a6b9dbdfded8d16b4969b91917a2550bbf33eccd1ecb3bd9e0753a47012e60f4efe720bbef2a2c5368529  libpgport-pkglibdir.patch.txt
6078defb3da67e7df96665cc130d32b69eebfcaf49d92eef368ea8eea8bb311fab56064c104bc97f53da9cd925301bef696b506af33e0b66d65bc6cd41ec7499  external-libpq.patch.txt
4fcf6a4037fb5765ef5913aaa0d76557d6ef2334760c2d702571db5f613e348879a370a527bf40ff441864d1bbf7ca773b9e14a1c2615d659c27697a6aa316e6  fix-test-temp-schema-cleanup.patch
5c9bfd9e295dcf678298bf0aa974347a7c311d6e7c2aa76a6920fcb751d01fd1ab77abbec11f3c672f927ad9deaa88e04e370c0b5cd1b60087554c474b748731  pltcl_create_tables.sql
"
